package com.sp.utils;

import cn.hutool.core.util.StrUtil;
import com.sp.exception.BusinessException;
import okhttp3.*;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.Instant;

/**
 * 车牌识别
 *
 * @author tong
 */
@Component
public class ImageRecognition {

    private final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
    @Value("${baidu.api.apikey}")
    private String clientId;
    @Value("${baidu.api.apisecret}")
    private String clientSecret;
    /**
     * 鉴权access_token
     */
    private String token;

    /**
     * 获取token的时间
     */
    private Instant tokenTimestamp;

    /**
     * 过期时长，单位为秒
     */
    private long expiresIn;

    /**
     * 获取鉴权access_token
     *
     * @return
     */
    private String getAccessToken() {
        if (StrUtil.isNotBlank(token) && Instant.now().isBefore(tokenTimestamp.plusSeconds(expiresIn))) {
            return token;
        }

        try {
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, "");
            Request request = new Request.Builder()
                    .url("https://aip.baidubce.com/oauth/2.0/token?client_id=" + clientId + "&client_secret=" + clientSecret + "&grant_type=client_credentials")
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .build();
            Response response = HTTP_CLIENT.newCall(request).execute();

            if (response.code() != 200) {
                throw new IOException("Failed to get access token: " + response.body().string());
            }

            JSONObject jsonObject = new JSONObject(response.body().string());
            tokenTimestamp = Instant.now();

            try {
                expiresIn = jsonObject.getLong("expires_in");
                return jsonObject.getString("access_token");
            } catch (Exception e) {
                token = null;
                System.err.println(jsonObject.getString("error_msg"));
                e.printStackTrace();
                return null;
            }
        } catch (Exception e) {
            // 异常已有token清空
            token = null;
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 识别车牌
     *
     * @param img
     * @return
     */
    public String getCarNumber(String img) {
        try {
            // img = URLDecoder.decode(img, "UTF-8").replaceAll(" ", "+");
            // 请求体url编码，才能传输
            img = URLEncoder.encode(img, "UTF-8");

            MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
            RequestBody body = RequestBody.create(mediaType, "multi_detect=false&multi_scale=false&image=" + img);

            Request request = new Request.Builder()
                    .url("https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=" + this.getAccessToken())
                    .method("POST", body)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .addHeader("Accept", "application/json")
                    .build();
            Response response = HTTP_CLIENT.newCall(request).execute();
            JSONObject jsonObject = new JSONObject(response.body().string());
            return jsonObject.getJSONObject("words_result").getString("number");
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("车辆图片提取车牌号失败");
        }
    }

}
